/*
 * Copyright (c) 2025 Industrial Software Feature Database
 */
package com.comac.ins.isfd.service.impl.section;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.comac.ins.common.core.exception.base.BaseException;
import com.comac.ins.common.core.utils.MapstructUtils;
import com.comac.ins.common.core.utils.StringUtils;
import com.comac.ins.common.encrypt.utils.EncryptUtils;
import com.comac.ins.isfd.constant.enums.IsfdSectionTypeEnum;
import com.comac.ins.isfd.domain.IsfdSection;
import com.comac.ins.isfd.domain.IsfdSectionResult;
import com.comac.ins.isfd.domain.bo.IsfdSectionBo;
import com.comac.ins.isfd.domain.vo.IsfdLayupEquivalentMaterialVo;
import com.comac.ins.isfd.util.CommonUtils;
import com.comac.ins.isfd.util.SectionCalculateUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * 型材库 C型框结构 实现类
 *
 * @author hxloongs
 * @date 2024-7-30
 */
@Service
public class IsfdSectionFcServiceImpl extends IsfdAbstractSectionService {
    @Override
    public String selectByType() {
        return IsfdSectionTypeEnum.FC.getValue();
    }

    @Override
    public String generateSerialNumber(IsfdSectionBo bo) {
        // 1. 参数校验
        checkBaseParams(bo);
        // 2. 生成型材编码
        // 编号规则：“FC”+自定义编号
        // 自定义编号 = t1铺层代号前两位 + t2铺层代号前两位 + t3铺层代号前两位 + 右补齐8位且自增
        String t1LayerCode = bo.getT1LayerCode();
        String t2LayerCode = bo.getT2LayerCode();
        String t3LayerCode = bo.getT3LayerCode();

        // 获取前两位，不足两位补零
        String t1Prefix = CommonUtils.getFirstNChars(t1LayerCode, 2);
        String t2Prefix = CommonUtils.getFirstNChars(t2LayerCode, 2);
        String t3Prefix = CommonUtils.getFirstNChars(t3LayerCode, 2);

        String preAttributeNumber = t1Prefix + t2Prefix + t3Prefix;
        String attributeNumber = super.geAttributeNumber(preAttributeNumber);
        return IsfdSectionTypeEnum.FC.getValue() + attributeNumber;
    }

    @Override
    public double[] calculate(IsfdSectionBo isfdSectionBo) {
        String t1LayerCode = isfdSectionBo.getT1LayerCode();
        String t2LayerCode = isfdSectionBo.getT2LayerCode();
        String t3LayerCode = isfdSectionBo.getT3LayerCode();

        IsfdLayupEquivalentMaterialVo t1Vo = iIsfdLayupEquivalentMaterialService.queryByLayCode(t1LayerCode);
        IsfdLayupEquivalentMaterialVo t2Vo = iIsfdLayupEquivalentMaterialService.queryByLayCode(t2LayerCode);
        IsfdLayupEquivalentMaterialVo t3Vo = iIsfdLayupEquivalentMaterialService.queryByLayCode(t3LayerCode);
        // 询铺层库的代码 t1 t2 t3，填充T E G 和 rho 、thm
        double[][] layerParametersFc = {{t1Vo.getT(), t1Vo.getExx(), t1Vo.getGxy(), t1Vo.getRho(), t1Vo.getX()},
            {t2Vo.getT(), t2Vo.getExx(), t2Vo.getGxy(), t2Vo.getRho(), t2Vo.getX()},
            {t3Vo.getT(), t3Vo.getExx(), t3Vo.getGxy(), t3Vo.getRho(), t3Vo.getX()}};
        double[] shapeParametersFc = {isfdSectionBo.getW1(), isfdSectionBo.getH(), isfdSectionBo.getW2(), isfdSectionBo.getBotOuterDistance()};
        double[] sectionPropertiesFc = new double[8];

        SectionCalculateUtils.calculateFcProfile(layerParametersFc, shapeParametersFc, sectionPropertiesFc);

        return sectionPropertiesFc;
    }

    @Transactional
    @Override
    public Boolean save(IsfdSectionBo bo) {
        // 1. 参数校验
        checkBaseParams(bo);
        checkParams(bo);

        // 2. 获取hash字段
        String hashUniqueKey = EncryptUtils.hashFields(bo.getType(), bo.getSerialNumber(), bo.getAttributeNumber(), bo.getMat1Id(),
            bo.getW1(), bo.getH(), bo.getW2(), bo.getT1LayerCode(), bo.getT2LayerCode(), bo.getT3LayerCode(), bo.getBotOuterDistance());

        // 3. 幂等校验
        Boolean isUpdate = super.checkUnique(bo, hashUniqueKey);

        // 4. 计算
        double[] sectionPropertiesFc = this.calculate(bo);

        // 5. 落表
        IsfdSection isfdSection = MapstructUtils.convert(bo, IsfdSection.class);
        isfdSection.setHashUniqueKey(hashUniqueKey);
        isfdSection.setRho(sectionPropertiesFc[6]);
        isfdSection.setThm(sectionPropertiesFc[7]);
        // 判断是新增业务还是修改业务，处理落表的方式不同
        if (isUpdate) {
            isfdSectionMapper.updateById(isfdSection);
            IsfdSectionResult isfdSectionResult = isfdSectionResultMapper.selectOne(new LambdaQueryWrapper<IsfdSectionResult>()
                .eq(IsfdSectionResult::getSecId, isfdSection.getId()));
            if (isfdSectionResult == null) {
                throw new BaseException("修改时，发现对应结果记录不存在，请确认后重试！");
            }
            isfdSectionResult.setE(sectionPropertiesFc[0]);
            isfdSectionResult.setG(sectionPropertiesFc[1]);
            isfdSectionResult.setXc(sectionPropertiesFc[2]);
            isfdSectionResult.setA(sectionPropertiesFc[3]);
            isfdSectionResult.setI1(sectionPropertiesFc[4]);
            isfdSectionResult.setI2(sectionPropertiesFc[5]);
            isfdSectionResultMapper.updateById(isfdSectionResult);
        } else {
            isfdSectionMapper.insert(isfdSection);
            IsfdSectionResult isfdSectionResult = new IsfdSectionResult();
            isfdSectionResult.setSecId(isfdSection.getId());
            isfdSectionResult.setE(sectionPropertiesFc[0]);
            isfdSectionResult.setG(sectionPropertiesFc[1]);
            isfdSectionResult.setXc(sectionPropertiesFc[2]);
            isfdSectionResult.setA(sectionPropertiesFc[3]);
            isfdSectionResult.setI1(sectionPropertiesFc[4]);
            isfdSectionResult.setI2(sectionPropertiesFc[5]);
            isfdSectionResultMapper.insert(isfdSectionResult);
        }
        return Boolean.TRUE;
    }

    private void checkBaseParams(IsfdSectionBo isfdSectionBo) {
        if (isfdSectionBo.getW1() == null) {
            throw new BaseException("w1不能为空，请确认后重试！");
        }
        if (isfdSectionBo.getH() == null) {
            throw new BaseException("h不能为空，请确认后重试！");
        }
        if (isfdSectionBo.getW2() == null) {
            throw new BaseException("w2不能为空，请确认后重试！");
        }
        if (isfdSectionBo.getT1LayerCode() == null) {
            throw new BaseException("t1铺层代号不能为空，请确认后重试！");
        }
        if (isfdSectionBo.getT2LayerCode() == null) {
            throw new BaseException("t2铺层代号不能为空，请确认后重试！");
        }
        if (isfdSectionBo.getT3LayerCode() == null) {
            throw new BaseException("t3铺层代号不能为空，请确认后重试！");
        }
        if (isfdSectionBo.getBotOuterDistance() == null) {
            throw new BaseException("框底边到外形面距离 不能为空，请确认后重试！");
        }
    }

    private void checkParams(IsfdSectionBo isfdSectionBo) {
        if (StringUtils.isBlank(isfdSectionBo.getSerialNumber()) || !isfdSectionBo.getSerialNumber().startsWith(IsfdSectionTypeEnum.FC.getValue())) {
            throw new BaseException("编号不能为空或者格式不正确（需要FC开头），请确认后重试！");
        }
        // 重新设置属性号和mat1_ID
        // 属性号 和 MATI_ID 是相同的；
        // 属性号 型材的物理特征，取值根据 型材编号规则产生，把型材编号的前缀类型字段替换掉，剩余的后缀就是属性号。
        // 属性号 最终小于等于8位，且全局唯一
        String serialNumber = isfdSectionBo.getSerialNumber();
        String attributeNumber = serialNumber.replace(IsfdSectionTypeEnum.FC.getValue(), "");
        isfdSectionBo.setAttributeNumber(attributeNumber);
        isfdSectionBo.setMat1Id(attributeNumber);
    }
}
